package com.yeyaomai.dksns.flowis.dao;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.mapreduce.GroupBy;
import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
import org.springframework.data.mongodb.core.mapreduce.MapReduceResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.yeyaomai.dksns.flowis.domain.Entity;

/**
 * 
 * @author dingtao@yayaomai.com
 */

public abstract class MongoDBBasicDao<T extends Entity> {

	@Resource
	protected MongoTemplate mongoTemplate;

	/**
	 * 用给定的 collectionName 创建一个集合
	 * 
	 * @param collectionName
	 *            集合名
	 */
	public void createCollection(String collectionName) {
		mongoTemplate.createCollection(collectionName);

	}

	/**
	 * 判断 collectionName 是否存在
	 * 
	 * @param collectionName
	 * @return
	 */
	public boolean collectionExists(String collectionName) {

		return mongoTemplate.collectionExists(collectionName);

	}

	/**
	 * 删除指定的 collectionName
	 * 
	 * @param collectionName
	 */

	public void dropCollection(String collectionName) {
		mongoTemplate.dropCollection(collectionName);
	}

	/**
	 * 
	 * 
	 * @param criteria
	 * @param clazz
	 */

	public T findOne(Criteria criteria, Class<T> clazz) {

		return mongoTemplate.findOne(new Query(criteria), clazz);
	}
	
	
	/**
	 * 
	 * 
	 * @param query
	 * @param clazz
	 */

	public T findOne(Query query, Class<T> clazz) {

		return mongoTemplate.findOne(query, clazz);
	}


	/**
	 * 
	 * @param criteria
	 * @param clazz
	 * @return
	 */
	public List<T> findList(Criteria criteria, Class<T> clazz) {

		return mongoTemplate.find(new Query(criteria), clazz);
	}

	/**
	 * 
	 * 
	 * @param query
	 * @param clazz
	 * @return
	 */
	public List<T> findList(Query query, Class<T> clazz) {
		return mongoTemplate.find(query, clazz);
	}

	/**
	 * 
	 * @param query
	 * @param clazz
	 * @return
	 */
	public T findAndRemove(Query query, Class<T> clazz) {

		return mongoTemplate.findAndRemove(query, clazz);

	}

	/**
	 * 
	 * @param entity
	 * @param collectionName
	 */
	public void remove(T entity, String collectionName) {

		mongoTemplate.remove(entity, collectionName);
	}

	/**
	 * 
	 * @param criteria
	 * @param clazz
	 */
	public void remove(Criteria criteria, Class<T> clazz) {
		mongoTemplate.remove(new Query(criteria), clazz);

	}

	/**
	 * 
	 * @param collectionName
	 * @param entity
	 */
	public void save(String collectionName, T entity) {
		mongoTemplate.save(entity, collectionName);
	}

	/**
	 * @param entity
	 */
	public void save(T entity) {
		mongoTemplate.save(entity);

	}

	/**
	 * @param query
	 * @param update
	 * @param entityClass
	 */
	public void update(Criteria criteria, Update update, Class<T> entityClass) {
		mongoTemplate.updateFirst(new Query(criteria), update, entityClass);
	}
	
	
	
	public long count(Query query,Class<T> clazz) {
		return mongoTemplate.count(query, clazz);
	}

	/**
	 * 
	 * @param criteria
	 * @param clazz
	 */
	public long count(Criteria criteria, Class<T> clazz) {
		return mongoTemplate.count(new Query(criteria), clazz);
	}
	
	/**
	 * 
	 * @param inputCollectionName
	 * @param mapFunction
	 * @param reduceFunction
	 * @param mapReduceOptions
	 * @param clazz
	 */
	public MapReduceResults<T> mapReduce(String inputCollectionName,String mapFunction,String reduceFunction,MapReduceOptions mapReduceOptions,Class<T> clazz){
		return mongoTemplate.mapReduce(inputCollectionName, mapFunction, reduceFunction, mapReduceOptions, clazz);
	}
	
	/**
	 * 
	 * @param criteria 查询条件
	 * @param inputCollectionName 集合
	 * @param groupBy 被统计
	 * @param clazz
	 */
	public GroupByResults<T> group(Criteria criteria,String inputCollectionName, GroupBy groupBy, Class<T> clazz){
		return mongoTemplate.group(criteria, inputCollectionName, groupBy, clazz);
	}
	
	/**
	 * 
	 * @param inputCollectionName 
	 * @param groupBy 
	 * @param clazz
	 */
	public GroupByResults<T> group(String inputCollectionName, GroupBy groupBy, Class<T> clazz){
		return mongoTemplate.group(inputCollectionName, groupBy, clazz);
	}


}
